#!/bin/bash

echo "---------------------------------------------------------------------------------------------------------------------------------------"
# (1)."string : REGEX"字符串匹配示例。要输出匹配到的字符串结果，需要使用"\("和"\)"，否则返回的将是匹配到的字符串数量。
expr abcde : 'ab\(.*\)' #ccde
expr abcde : 'ab\(.\)'  #c
expr abcde : 'ab.*'     #5
expr abcde : 'ab.'      #3
expr abcde : '.*cd*'    #4
# 由于REGEX中隐含了"^"，所以使得匹配时都是从string首字符开始的。
expr abcde : 'cd.*' #0

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (2)."index string chars"用法示例。
# 该表达式是从string中搜索chars中某个字符的位置，这个字符是string中最靠前的字符。例如：
expr index abcde dec #3
# 该命令将对字符串"dec"逐字符分解，首先分解得到第一个字符d，从abcde中搜索到d的位置为4，再分解得到第二个字符e，
# 该字符在abcde中的位置为5，最后得到的字符是c，该字符在abcde中的位置为3。其中3是最靠前的字符，所以命令返回的结果为3。
expr index abcde xdc #3
expr index abcde xdc #3
expr index abcde adc #1
expr index abcde xya #1
expr index abcde aya #1
expr index abcde aye #1
# 如果chars中的所有字符都不存在于string中，则返回0。
expr index abcde q #0

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (3)."substr string pos len"用法示例。
# 该表达式是从string中取出从pos位置开始长度为len的子字符串。如果pos或len为非正整数时，将返回空字符串。
expr substr abcde 2 3 #bcd
expr substr abcde 2 4 #bcde
expr substr abcde 2 5 #bcde
expr substr abcde 1 1 #a
expr substr abcde 1 0
expr substr abcde 0 1

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (4)."length string"用法示例。该表达式是返回string的长度，其中string不允许为空，否则将报错，所以可以用来判断变量是否为空。
expr length abcde          #5
expr length 111            #3
expr length 哈哈         #6
expr length 😄           #4
expr length 😔开心haha #14
expr length $xxx           #expr: syntax error
xxx=😄
expr length $xxx #4
if [ $? -ne 0 ]; then echo '$xxx is null'; else echo '😁'; fi

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (5)."+ token"用法示例。
# expr中有些符号和关键字有特殊意义，如"match"、"index"、"length"，如果要让其成为字符，使用该表达式将任意token强制解析为普通字符串。
expr index + length g                #4
expr length + index                  #5
expr index 'length : "\(length\)"' g #4

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (6).算术运算用法示例。
expr 1 + 2   #3
expr 2 \* 3  #6
expr 2 '*' 3 #6
expr 3 / 2
expr 3 % 2

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (7).比较操作符< <= = == != >= >用法示例。其中"<"和">"是正则表达式正的锚定元字符，且"<"会被shell解析为重定向符号，所以需要转义或用引号包围。
# 这些操作符会首先会将两端的参数转换为数值，如果转换成功，则采用数值比较，
# 如果转换失败，则按照字符集的排序规则进行字符大小比较。比较的结果若为true，则expr返回1，否则返回0。
a=1
expr $a == 1
expr $a == 2

echo "----------------------------------------------------------------------------------------------------------------------------------------"
# (8).逻辑连接符号"&"和"|"用法示例。这两个符号都需要转义，或使用引号包围。
# "&"表示如果两个参数都非0，则返回第一个参数，否则返回0。但任意一个参数为空，则expr报错。除非空字符串使用引号包围，则处理方法和0一样。
# "|"表示如果第一个参数非0，则返回第一个参数的值，否则返回第二个参数。但如果任意一个参数为空，则expr报错。除非空字符串使用引号包围，则处理方法和0一样。
expr "$abc" '|' 1
expr "$abc" '&' 1
expr 0 '&' abc
expr abc '&' 0
expr 0 '|' abc
expr abc '&' cde
expr abc '|' cde
